import Icon from '@/components/Icon';
import NavBar from '@/components/NavBar';
import { useAppDispatch, useAppSelector } from '@/store';
import { clearSuggestsAction, getSuggestsAction } from '@/store/action/search';
import { getLocalHistories, removeLocalHistories, setLocalHistories } from '@/utils/storage';
import DOMpurify from 'dompurify';
import { uniq } from 'lodash';
import React, { useEffect, useRef, useState } from 'react';
import { useHistory } from 'react-router-dom';
import styles from './index.module.scss';

export default function Search() {
  const dispatch = useAppDispatch();
  const history = useHistory();
  const [keyword, setKeyword] = useState('');
  const { suggests } = useAppSelector((state) => state.search);

  const { histories, handleAddHistory, handleClearHistory } = useSearchHistory();

  const timerIdRef = useRef(-1);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setKeyword(e.target.value);
    clearTimeout(timerIdRef.current);
    timerIdRef.current = window.setTimeout(() => {
      if (!e.target.value) {
        dispatch(clearSuggestsAction());
        return;
      }
      dispatch(getSuggestsAction(e.target.value));
    }, 700);
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handleSearch();
    }
  };

  const handleSearch = (str?: string) => {
    handleAddHistory(str || keyword);
    history.push({ pathname: '/search/result', search: `q=${str || keyword}` });
  };

  useEffect(() => {
    return () => {
      clearTimeout(timerIdRef.current);
      dispatch(clearSuggestsAction());
    };
  }, [dispatch]);
  return (
    <div className={styles.root}>
      <NavBar
        right={
          <span onClick={(e) => handleSearch()} className="search-text">
            搜索
          </span>
        }
      >
        <div className="navbar-search">
          <Icon type="iconbtn_search" className="icon-search" />

          <div className="input-wrapper">
            <input
              onChange={handleChange}
              onKeyDown={handleKeyDown}
              value={keyword}
              type="text"
              placeholder="请输入关键字搜索"
            />

            <Icon onClick={() => setKeyword('')} type="iconbtn_tag_close" className="icon-close" />
          </div>
        </div>
      </NavBar>

      {!keyword && !!histories.length && (
        <div className="history" style={{ display: 'block' }}>
          <div className="history-header">
            <span>搜索历史</span>
            <span onClick={handleClearHistory}>
              <Icon type="iconbtn_del" />
              清除全部
            </span>
          </div>

          <div className="history-list">
            {histories.map((item, index) => (
              <span onClick={() => handleSearch(item)} className="history-item" key={index}>
                {item}
                <span className="divider"></span>
              </span>
            ))}
          </div>
        </div>
      )}

      <div className="search-result">
        {suggests.map((item, index) => {
          return (
            <div key={index} className="result-item" onClick={() => handleSearch(item)}>
              <Icon className="icon-search" type="iconbtn_search" />
              <div
                className="result-value"
                dangerouslySetInnerHTML={{
                  __html: DOMpurify.sanitize(highlight(keyword, item)),
                }}
              />
            </div>
          );
        })}
      </div>
    </div>
  );
}

function highlight(keyword: string, result: string) {
  const reg = new RegExp(`(${keyword})`, 'gi');
  return result.replace(reg, '<span>$1</span>');
}

function useSearchHistory() {
  const [histories, setHistories] = useState(getLocalHistories());

  const handleAddHistory = (str: string) => {
    const newList = uniq([...histories, str]);
    setHistories(newList);
    setLocalHistories(newList);
  };

  const handleClearHistory = () => {
    setHistories([]);
    removeLocalHistories();
  };

  return {
    histories,
    handleAddHistory,
    handleClearHistory,
  };
}
